//-------------------------------------------------------------------------------------
// <copyright file="Exists.cs" company="Microsoft">
// Copyright (c) Microsoft Corporation.  All rights reserved.
// THIS CODE AND INFORMATION ARE PROVIDED "AS IS" WITHOUT WARRANTY OF ANY 
// KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
// PARTICULAR PURPOSE.
// </copyright>
// <summary>
//      Checks whether an assembly is deployed in a BizTalk installation.
// </summary>  
//-------------------------------------------------------------------------------------

using System;

namespace Microsoft.Sdc.Tasks.BizTalk2006.Assembly
{
    #region Using directives

    using BizTalk.ApplicationDeployment;
    using Microsoft.Build.Framework;
    using System.IO;
    using System.Globalization;

    #endregion

    /// <summary>
    /// Checks whether an assembly is deployed in a BizTalk installation.
    /// </summary>
    /// <remarks>
    /// <code>
    /// <![CDATA[<BizTalk2006.Assembly.ExistsResource Application="EAIApplication" ResourcePath="Path" ResourceType="BizTalkAssembly" Server="server" Database="database" />]]>
    /// </code>
    /// <para>where:</para>
    /// <para><i>ResourcePath (Required)</i></para>
    /// <para>
    /// The path of the resource to check for.
    /// </para>
    /// <para><i>ResourceType (Required)</i></para>
    /// <para>
    /// The ResourceType of the resource.
    /// <list type="string">
    ///     <item>System.BizTalk:Assembly</item>
    ///     <item>System.BizTalk:Bam</item>
    ///     <item>System.BizTalk:Bas</item> 
    ///     <item>System.BizTalk:BizTalkAssembly</item> 
    ///     <item>System.BizTalk:BizTalkBinding</item>
    ///     <item>System.BizTalk:Certificate</item>
    ///     <item>System.BizTalk:Com</item> 
    ///     <item>System.BizTalk:File</item> 
    ///     <item>System.BizTalk:PostProcessingScript</item> 
    ///     <item>System.BizTalk:PreProcessingScript</item> 
    ///     <item>System.BizTalk:Rules</item> 
    ///     <item>System.BizTalk:WebDirectory</item> 
    /// </list>
    /// </para>
    /// <para><i>Application</i></para>
    /// <para>
    /// The BizTalk application in which the resource should be.
    /// </para>
    /// <para><i>server</i></para>
    /// <para>
    /// The logical name of the server hosting the BizTalk management database. If neither this nor the
    /// database name are specified then the installation will default to the local installation.
    /// </para>
    /// <para><i>database</i></para>
    /// <para>
    /// The name of the BizTalk management database. If neither this nor the server name are specified 
    /// then the installation will default to the local installation.
    /// </para>
    /// <para><i>username</i></para>
    /// <para>
    /// The username to use to connect to the database if using SQL Server security. The default is to
    /// connect using Windows Integrated security.
    /// </para>
    /// <para><i>password</i></para>
    /// <para>
    /// The password to use to connect to the database if using SQL Server security. The default is to
    /// connect using Windows Integrated security.
    /// </para>
    /// <b>When the following Types are used. The ResourcePath should have the BizTalk Luid instead of the ResourcePath.
    /// <list type="string">
    ///   <item>System.BizTalk:Bas</item> 
    ///   <item>System.BizTalk:Certificate</item>
    ///   <item>System.BizTalk:Rules</item> 
    ///   <item>System.BizTalk:WebDirectory</item> 
    /// </list>
    /// </b>
    /// </remarks>
    /// <example>
    /// <code><![CDATA[
    /// <Project>
    ///     <PropertyGroup>
    ///         <AssemblyExists />
    ///     </PropertyGroup>
    ///     <Target Name="Test" >
    ///         <BizTalk2006.Assembly.Exists 
    ///             ResourcePath="C:\BizTalkAssemlby.dll"
    ///             ResourceType="System.BizTalk:BizTalkAssembly"
    ///             Server="." 
    ///             Database="BizTalkMgmtDb" 
    ///             Username="sa" 
    ///             Password="foo">
    ///             <Output TaskParameter="DoesExist" PropertyName="AssemblyExists" />
    ///         </BizTalk2006.Assembly.Exists>
    ///     </Target>
    /// </Project>
    /// ]]></code>
    /// </example>
    public class ExistsResource : BizTalk2004.BizTalk2004TaskBase
    {
        #region Member Variables

        private string application;
        private string resourceType;
        private string resourcePath;
        private bool doesExist;

        #endregion

        #region Properties

        /// <summary>
        /// Gets or sets the application.
        /// </summary>
        /// <value>The application.</value>
        public string Application
        {
            get { return this.application; }
            set { this.application = value; }
        }

        /// <summary>
        /// Gets or sets the resourcetype
        /// </summary>
        /// <value>The resource type. 
        /// The following resource types can be filled
        /// <list type="string">
        ///     <item>System.BizTalk:Assembly</item>
        ///     <item>System.BizTalk:Bam</item>
        ///     <item>System.BizTalk:Bas</item> 
        ///     <item>System.BizTalk:BizTalkAssembly</item> 
        ///     <item>System.BizTalk:BizTalkBinding</item>
        ///     <item>System.BizTalk:Certificate</item>
        ///     <item>System.BizTalk:Com</item> 
        ///     <item>System.BizTalk:File</item> 
        ///     <item>System.BizTalk:PostProcessingScript</item> 
        ///     <item>System.BizTalk:PreProcessingScript</item> 
        ///     <item>System.BizTalk:Rules</item> 
        ///     <item>System.BizTalk:WebDirectory</item> 
        /// </list>
        /// </value>
        [Required]
        public string ResourceType
        {
            get { return this.resourceType; }
            set { this.resourceType = value; }
        }

        /// <summary>
        /// Gets or sets the display name of the assembly.
        /// </summary>
        /// <value>
        /// The display name of the assembly.
        /// </value>
        [Required]
        public string ResourcePath
        {
            get { return this.resourcePath; }
            set { this.resourcePath = value; }
        }

        /// <summary>
        /// Gets whether the assembly does exist in the deployment.
        /// </summary>
        /// <value>
        /// <b>true</b> if the assembly does exist, or <b>false</b> otherwise.
        /// </value>
        [Output]
        public bool DoesExist
        {
            get { return this.doesExist; }
            protected set { this.doesExist = value; }
        }

        #endregion

        #region Methods

        /// <summary>
        /// Executes the task.
        /// </summary>
        protected override void InternalExecute()
        {
            this.DoesExist = false;

            BizTalk2004.Configuration.BizTalkInstallation installation = this.GetInstallation();
            string resourceType = this.ResourceType;
            resourceType = SdmParser.GetInstance().TransformResourceType(resourceType);

            using (Group group = new Group())
            {
                group.DBServer = installation.Server;
                group.DBName = installation.Database;

                Application app = group.Applications[this.Application];
                if (app != null)
                {
                    app.UILevel = 2;

                    string name;

                    switch (resourceType)
                    {
                        case "System.BizTalk:Assembly":
                        case "System.BizTalk:BizTalkAssembly":
                            System.Reflection.Assembly ass = System.Reflection.Assembly.ReflectionOnlyLoadFrom(this.ResourcePath);
                            name = ass.FullName;
                            Log.LogMessage(string.Format(CultureInfo.InvariantCulture, "Checking for resource: {0} ({1}) of Application {2}", name, this.ResourceType, this.Application));
                            break;
                        case "System.BizTalk:BizTalkBinding":
                        case "System.BizTalk:Com":
                        case "System.BizTalk:File":
                        case "System.BizTalk:PostProcessingScript":
                        case "System.BizTalk:PreProcessingScript":
                        case "System.BizTalk:Bam":
                            FileInfo info = new FileInfo(this.ResourcePath);
                            name = info.Name;
                            Log.LogMessage(string.Format(CultureInfo.InvariantCulture, "Checking for resource: {0} ({1}) of Application {2}", name, this.ResourceType, this.Application));
                            break;
                        case "System.BizTalk:WebDirectory":
                        case "System.BizTalk:Bas":
                        case "System.BizTalk:Certificate":
                        case "System.BizTalk:Rules":
                            // When these types are used, the resourcepath should be equal to the BizTalk Luid.
                            name = this.ResourcePath;
                            break;
                        default:
                            throw new Exception("Invalid ResourceType");
                    }

                    foreach (IDeploymentResource resource in app.ResourceCollection)
                    {
                        if (resource.Luid.Equals(name))
                        {
                            Log.LogMessage(string.Format(CultureInfo.InvariantCulture, "Resource: {0} ({1}) of Application {2} exists", this.ResourcePath, this.ResourceType, this.Application));
                            this.DoesExist = true;
                            break;
                        }
                    }
                }
            }
        }
        #endregion
    }
}

